import json

from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from django.views import View
from django.db import transaction
from hourses.models import Area, House, Facility, HouseImage
from ihome.utils.qiniuyun.qiniu_storage import storage
from ihome.utils.views import LoginRequiredMixin
from orders.models import Order
from users.models import User


class GetAreaInfo(View):
    '''城区列表类视图'''
    def get(self,request):
        '''get请求'''
        areas = Area.objects.all()

        data = []

        for area in areas:
            data.append({"aid":area.id,
                                    "aname":area.name})


        return JsonResponse({"errno":0, "errmsg": "已上传",
                             "data":data})


class GetHouseSource(LoginRequiredMixin,View):
    '''获取房源信息类视图'''

    def get(self,request):
        '''get请求'''
        user = request.user

        try:
            houses = House.objects.filter(user=user.id)
            count = houses.count()
        except Exception as e:

            return JsonResponse({"errno": "4004", "errmsg": "数据库读取出错"})

        if count > 0:
            house_list = []
            for house in houses:
                house_list.append(
                    {
                        "address":house.address,
                        "area_name":house.area.name,
                        "ctime":house.create_time.strftime('%Y-%m-%d'),
                        "house_id": house.id,
                        "img_url":house.index_image_url,
                        "order_count":house.order_count,
                        "price":house.price,
                        "room_count":house.room_count,
                        "title":house.title,
                        "user_avatar":user.avatar.name
                    }
                )

            data = {"houses":house_list}
            return JsonResponse({"errno": "0", "errmsg": "ok","data":data})

        else:
            return JsonResponse({"errno":"0", "errmsg": "还未上传房源","data":{"houses":[]}})



class PublicHouseSource(View):
    '''发布房源信息类视图'''
    def post(self,request):

        '''json传参,返回数据格式{
            "errno": "0",
            "errmsg": "发布成功",
            "data": {
                "house_id": 1
            }}
        '''
        # 获取用户信息
        if not request.user.username:
            return JsonResponse({"errno":"4101", "errmsg": "用户未登录"})
        try:
            count = House.objects.filter(user_id=request.user).count()
        except Exception:
            return JsonResponse({"errno": "4004", "errmsg": "数据库读取错误"})

        if count > 100:
            return JsonResponse({"errno": "4001", "errmsg": "数量超出上限"})

        user_dict = json.loads(request.body)
        title = user_dict.get('title')
        price = user_dict.get('price')
        area_id = user_dict.get('area_id')
        address = user_dict.get('address')
        room_count = user_dict.get('room_count')
        acreage = user_dict.get('acreage')
        unit = user_dict.get('unit')
        capacity = user_dict.get('capacity')
        beds = user_dict.get('beds')
        deposit = user_dict.get('deposit')
        min_days = user_dict.get('min_days')
        max_days = user_dict.get('max_days')
        facility = user_dict.get('facility')

        if not all([title,address]):
            return JsonResponse({"errno":"4103", "errmsg": "缺少必传参数"})

        area_id = Area.objects.get(id=area_id)
        # 显式的开启一个事务
        try:
            # 显式的开启一个事务
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()
                house = House.objects.create(
                        user = request.user,
                        area = area_id,
                        title = title,
                        price = price,
                        address = address,
                        room_count = room_count,
                        acreage = acreage,
                        unit = unit,
                        capacity = capacity,
                        beds = beds,
                        deposit = deposit,
                        min_days = min_days,
                        max_days = max_days)
                for f in facility:
                    house.facility.add(f)
                # 清除保存点
                transaction.savepoint_commit(save_id)
        except Exception as e:
            return JsonResponse({"errno": "4004",
                                     "errmsg": "房屋信息上传失败"})

        house_id = house.id

        data = {"house_id":house_id}

        return JsonResponse({"errno":0, "errmsg": "已上传",
                             "data":data})


    def get(self, request):

        # 获取并接收参数
        search_info = request.GET.dict()
        aid = search_info.get('aid')
        sd = search_info.get('sd')
        ed = search_info.get('ed')
        sk = search_info.get('sk')
        p = search_info.get('p')

        try:
            # 获取地区信息
            area = Area.objects.get(id=aid)
        except Exception as e:
            return JsonResponse({'errno': 4002, 'errmsg': '无数据'})

        # 获取所有匹配的房屋（在查询时间内其他人未预定）
        houses = House.objects.filter(area=area)
        house_id_set = set()
        if ed and sd:
            orders = Order.objects.filter(house__in=houses)

            # 过滤可预定房屋
            for order in orders:

                if order.status in [0, 3, 4, 5, 6]:
                    continue

                if str(order.begin_date) < sd < str(order.end_date):
                    house_id_set.add(order.house.id)
                if str(order.begin_date) < ed < str(order.end_date):
                    house_id_set.add(order.house.id)
                if sd < str(order.begin_date) and ed > str(order.end_date):
                    house_id_set.add(order.house.id)

        if sk == 'new':
            ordering = 'create_time'
        elif sk == 'booking':
            ordering = '-order_count'
        elif sk == 'price-inc':
            ordering = 'price'
        elif sk == 'price-des':
            ordering = '-price'

        try:
            # 获取房屋对象
            if house_id_set:
                houses = House.objects.filter(Q(area=area) & ~Q(id__in=house_id_set)).order_by(ordering)
            else:
                houses = House.objects.filter(area=area).order_by(ordering)
        except Exception:
            return JsonResponse({'errno': 4001, 'errmsg': 'DBERR'})

        # 生成房屋数据
        # total_page = 0
        data = {'houses': [], "total_page": 1}
        for house in houses:
            data['houses'].append({
                "address": house.address,
                "area_name": house.area.name,
                "ctime": house.create_time.strftime('%Y-%m-%d %H:%M:%S'),
                "house_id": house.id,
                "img_url":house.index_image_url,
                "order_count": house.order_count,
                "price": house.price,
                "room_count": house.room_count,
                "title": house.title,
                "user_avatar":house.user.avatar.name
            })

        # 返回响应数据
        return JsonResponse({'errno': '0', 'errmsg': 'ok', 'data': data})


class UploadHouseImage(LoginRequiredMixin,View):
    '''上传房屋图片类视图'''
    def post(self,request):
        '''
        :param request:
        :return: {
                    "data": {
                        "url": "http://oyucyko3w.bkt.clouddn.com/FmWZRObXNX6TdC8D688AjmDAoVrS"
                    },
                    "errno": "0",
                    "errmsg": "图片上传成功"
                }
        '''
        image_file = request.FILES.get('house_image').read()
        ret = storage(image_file)
        image_url = 'http://qerta0kqb.bkt.clouddn.com/'+str(ret)
        request_url = request.path
        id = int(request_url.split('/')[-2])
        try:
            house = House.objects.get(id=id)
            house_image = HouseImage.objects.create(house=house,
                                      url=image_url)
            House.objects.filter(id=id).update(index_image_url=image_url)
        except Exception as e:
            return JsonResponse({"errno": "4004",
                                     "errmsg": "房屋信息上传失败"})
        data = {
                "url":house_image.url
            }

        return JsonResponse({"errno":0, "errmsg": "图片上传成功",
                             "data":data})


class RecommendFirstPage(View):
    '''首页推荐视图'''
    def get(self,request):
        '''
        "data": [
        {
        "house_id": 4,
        "img_url": "http://oyucyko3w.bkt.clouddn.com/FhgvJiGF9Wfjse8ZhAXb_pYObECQ",
        "title": "555"
        :param request:
        :return:
        '''

        try:
            houses = House.objects.all().order_by('-create_time')

            data_list=[]
            for house in houses[0:5]:
                data_list.append(
                    {
                        "house_id":house.id,
                        "img_url": house.index_image_url,
                        "title": house.title
                    }
                    )

        except Exception as e:
            return JsonResponse({"errno": "4004",
                                     "errmsg": "房屋信息读取失败"})

        else:
            return JsonResponse({"errno":0, "errmsg": "ok",
                             "data":data_list})


class HousedetailedInfoView(View):
    '''房屋详情页类视图'''
    def get(self,request):
        '''

        :param request:
        :return: Jsondict
        '''
        request_url = request.path
        id = int(request_url.split('/')[-1])
        user = request.user
        try:
            house = House.objects.get(id=id)
            user_owner = User.objects.get(id=house.user_id)
            house_images = HouseImage.objects.filter(house=house)
            orders = Order.objects.filter(house=house).order_by('-create_time')
        except Exception as e:
            return JsonResponse({"errno": "4004",
                                     "errmsg": "房屋信息读取失败"})
        else:
            image_list = []
            for image in house_images:
                image_list.append(image.url)

            facility_lists = []
            for facility in house.facility.all():
                facility_lists.append(facility.id)

            comment_lists = []
            for order in orders:
                try:
                    user_name = order.user.username
                    comment_lists.append(
                        {
                            "comment": order.comment,
                            "ctime": order.create_time.strftime('%Y-%m-%d %H:%M:%S'),
                            "user_name": order.user.username,
                        })
                except Exception:
                    comment_lists.append(
                        {
                            "comment":"",
                            "ctime":"",
                            "user_name":"",
                        })


            data = {
            "house": {
            "acreage": house.acreage,
            "address": house.address,
            "beds": house.beds,
            "capacity":house.capacity,
            "comments":comment_lists,
            "deposit":house.deposit,
            "facilities":facility_lists,
            "hid":house.id,
            "img_urls":image_list,
            "max_days":house.max_days,
            "min_days":house.min_days,
            "price":house.price,
            "room_count":house.room_count,
            "title":house.title,
            "unit":house.unit,
            "user_avatar":user_owner.avatar.name,
            "user_id":user_owner.id,
            "user_name":user_owner.username},
            "user_id": 1 if request.user.username==house.user.username else -1}
            return JsonResponse({"errno":0,"errmsg":"ok","data":data})
